package org.jeecg.modules.charge.service.impl;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradePayRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.response.AlipayTradePayResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.ComUtil;
import org.jeecg.common.util.DateUtils;
import org.jeecg.common.util.SsoUtil;
import org.jeecg.common.util.StringUtils;
import org.jeecg.common.util.wx.UnifiedOrderWxPay;
import org.jeecg.common.util.wx.WXPayUtil;
import org.jeecg.config.Sm4Util;
import org.jeecg.entity.basedata.BaseRoom;
import org.jeecg.entity.charge.*;
import org.jeecg.enums.InvoiceTypeEnum;
import org.jeecg.enums.PayChannelEnum;
import org.jeecg.enums.PayModeEnum;
import org.jeecg.enums.PayStatusEnum;
import org.jeecg.enums.common.PayTypeEnum;
import org.jeecg.enums.meter.RefundStatusEnum;
import org.jeecg.model.charge.reqvo.DayReportReqVo;
import org.jeecg.model.charge.resvo.DayReportRespVo;
import org.jeecg.modules.charge.entity.ChargeBillsOrder;
import org.jeecg.modules.charge.entity.ChargePayConfig;
import org.jeecg.modules.charge.entity.ChargePayNotify;
import org.jeecg.modules.charge.entity.PayAccountConfig;
import org.jeecg.modules.charge.mapper.ChargeBillsOrderMapper;
import org.jeecg.modules.charge.mapper.ChargePayConfigMapper;
import org.jeecg.modules.charge.service.*;
import org.jeecg.modules.system.entity.FFTCreateOrder;
import org.jeecg.modules.system.entity.FFTFeeItem;
import org.jeecg.modules.system.mapper.SysDepartMapper;
import org.jeecg.service.IFeignBaseDataService;
import org.jeecg.service.IFeignChargeService;
import org.jeecg.vo.charge.ChargeOrderReqVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.stream.Collectors;

/**
 * @Description: 订单表
 * @Author: jeecg-boot
 * @Date: 2019-08-15
 * @Version: V1.0
 */
@Service
@Slf4j
public class ChargeBillsOrderServiceImpl extends ServiceImpl<ChargeBillsOrderMapper, ChargeBillsOrder> implements IChargeBillsOrderService {
    private final Queue<String> payQueue = new ConcurrentLinkedQueue<String>();
    @Autowired
    private SysDepartMapper sysDepartMapper;
    @Autowired
    private ChargeBillsOrderMapper chargeBillsOrderMapper;
    @Autowired
    private ChargePayConfigMapper chargePayConfigMapper;
    @Autowired
    private IChargeFeeitemService chargeFeeitemService;
    @Autowired
    private IChargeInvoiceRequestService chargeInvoiceRequestService;
    @Autowired
    private IChargeBillsService chargeBillsService;
    @Autowired
    private IChargeFeeRuleService chargeFeeRuleService;
    @Autowired
    private IFeignChargeService feignChargeService;
    @Autowired
    private IFeignBaseDataService feignBaseDataService;

    @Value("${pay.fftEncryptKey}")
    private String fftEncryptKey; //付费通加密key


    /**
     * 日常收费 - 提交
     * @param reqVo
     * @return
     */
    @Override
    @Transactional(rollbackFor=Exception.class)
    public Result<ChargeBillsOrder> unLineCharge(ChargeOrderReqVo reqVo){
        LoginUser loginUser = SsoUtil.getLoginUser();
        Date now = new Date();
        BaseRoom room = feignBaseDataService.getByRoomIds(reqVo.getRoomId(),loginUser.getTenantId());
        if (room == null) return Result.error("房间信息系统中不存在,收款失败！");
        //订单信息
        ChargeBillsOrder chargeBillsOrder = new ChargeBillsOrder();
        chargeBillsOrder.setId(IdWorker.getIdStr());
        chargeBillsOrder.setCreateBy(loginUser.getId());
        chargeBillsOrder.setCreateTime(now);
        chargeBillsOrder.setPayTime(now);
        //临时存放项目代号，用于生成账单时的项目代号
        String projectCode = sysDepartMapper.getProjectCode(room.getProjectId());
        chargeBillsOrder.setVerifyAdminId(projectCode);
        String sn = StringUtils.createSn(projectCode, 3);
        chargeBillsOrder.setSn(sn);
        chargeBillsOrder.setProjectId(room.getProjectId());
        chargeBillsOrder.setFloorId(room.getFloorId());
        chargeBillsOrder.setFeeitemId(reqVo.getFeeId());
        chargeBillsOrder.setRoomId(reqVo.getRoomId());
        chargeBillsOrder.setPayFee(reqVo.getPay().doubleValue());//实收金额
        chargeBillsOrder.setPayDue(reqVo.getDue());
        chargeBillsOrder.setPayReduced(reqVo.getDue().subtract(reqVo.getPay()));
        chargeBillsOrder.setPayMode(PayModeEnum.PAY_MODE_OFFLINE.getCode());//支付类型
        chargeBillsOrder.setPayChannel(PayChannelEnum.PAY_CHANNEL_OFFLINE.getCode());//支付渠道
        chargeBillsOrder.setPayType(reqVo.getPayType()); //支付方式
        chargeBillsOrder.setPayStatus(PayStatusEnum.PAY_STATUS_YES.getCode());
        chargeBillsOrder.setStatus(1);  //默认账单有效
        chargeBillsOrder.setTenantId(loginUser.getTenantId());
        chargeBillsOrder.setInvoiceType(reqVo.getInvoiceType());
        chargeBillsOrder.setInvoiceEmail(reqVo.getInvoiceEmail());
        chargeBillsOrder.setInvoiceMobile(reqVo.getInvoiceType());
        chargeBillsOrder.setInvoiceName(reqVo.getInvoiceName());
        List<ChargeBills> billsList = this.refreshChargeBills(reqVo, chargeBillsOrder);
        this.save(chargeBillsOrder);
        chargeBillsService.updateBillsBatch(billsList);
        return Result.ok(chargeBillsOrder);
//        // 用于插入后面开电子发票的请求备注账单ID
//        String invoiceBills = "";
//        List<String> bids = new ArrayList<String>();
//        Integer winOrFail = 0;
//        List<ChargeInvoiceInfo> infos = new ArrayList<ChargeInvoiceInfo>();
//        try {
//            //电票开具
//            if (InvoiceTypeEnum.INVOICE_TYPE_ELE.getCode().equals(chargeInvoice.getTicket())) {
//                if ("1".equals(chargeInvoice.getIsDay())) {
//                    for (ChargeBillsJump bill : chargeInvoice.getBillsList()) {
//                        if (StringUtils.isNotEmpty(bill.getId())) {
//                            invoiceBills += bill.getId()+",";
//                        }
//                    }
//                    if(StringUtils.isNotEmpty(invoiceBills)){
//                        invoiceBills = invoiceBills.substring(0,invoiceBills.length()-1);
//                    }
//                }
//                chargeBillsOrder.setPayStatus(1);
//                chargeBillsOrder.setBillids(invoiceBills);
//                winOrFail = 1;
//                winOrFail = refreshChargeBills(chargeInvoice, chargeBillsOrder);
//
//                // 开票
//                this.chargeBlueInvoice(chargeBillsOrder);
//
//                //纸票开具
//            }else if (InvoiceTypeEnum.INVOICE_TYPE_PAPER.getCode().equals(chargeInvoice.getTicket())) {
//                //判断
//                String pjId = chargeInvoiceService.getIdByInvoice(chargeInvoice.getInvoiceHm(), chargeInvoice.getInvoiceDm());
//                if (null != pjId) {
//                    chargeInvoice.setId(pjId);
//                    chargeInvoice.setUpdateBy(crrUserId);
//                    chargeInvoice.setUpdateDate(new Date());
//                    Integer invoiceResult = chargeInvoiceService.updateInvoices(chargeInvoice);
//                    //票据插入成功
//                    for (ChargeBillsJump bill : chargeInvoice.getBillsList()) {
//                        bill.setInvoiceGrnno(chargeInvoice.getInvoiceDm());
//                        bill.setInvoiceNo(chargeInvoice.getInvoiceHm());
//                        bill.setInvoiceId(pjId);
//                        bill.setCreateBy(crrUserId);
//                        bill.setUpdateBy(crrUserId);
//                        bill.setUpdateDate(now);
//                        bill.setCreateDate(now);
//                        if(StringUtils.isNotEmpty(bill.getId())) {
//                            String[] ids = bill.getId().split(",");
//                            for (int i = 0; i < ids.length; i++) {
//                                bids.add(ids[i]);
//                            }
//                        }
//                        ChargeInvoiceInfo info = new ChargeInvoiceInfo(bill);
//                        infos.add(info);
//                    }
//                    if (invoiceResult > 0) {
//                        Boolean addInfos = chargeInvoiceInfoService.saveBatch(infos);
//                        if (addInfos) {
//                            //日常收费
//                            if ("1".equals(chargeInvoice.getIsDay())) {
//                                winOrFail = refreshChargeBills(chargeInvoice, chargeBillsOrder);
//                            }
//                            //非日常收费（其他收费）
//                            if ("0".equals(chargeInvoice.getIsDay())){
//                                winOrFail = 1;
//                                chargeBillsOrder.setBillids(pjId);
//                            }
//                        }
//                    }
//                    chargeBillsOrder.setPayStatus(1);
//                }
//            }else {
//                //无票据。只处理对应日常收费，如果是无票据的其他收费直接失败
//                if ("1".equals(chargeInvoice.getIsDay())) {
//                    winOrFail = refreshChargeBills(chargeInvoice, chargeBillsOrder);
//                    for (ChargeBillsJump bill : chargeInvoice.getBillsList()) {
//                        if(StringUtils.isNotEmpty(bill.getId())) {
//                            String[] ids = bill.getId().split(",");
//                            for (int i = 0; i < ids.length; i++) {
//                                bids.add(ids[i]);
//                            }
//                        }
//                    }
//                    chargeBillsOrder.setBillids(String.join(",",bids));
//                    chargeBillsOrder.setPayStatus(PayStatusEnum.PAY_STATUS_YES.getCode());
//                }
//            }
//            //修改账单批量缴费优惠金额
//            for (ChargeBillsJump jump : chargeInvoice.getBillsList()){
//                if (!BigDecimal.ZERO.equals(jump.getPayReduced())){
//                    //收款账单id
//                    String[] ids = jump.getId().split(",");
//                    //每个账单优惠金额 = 总的金额 / 账单个数
//                    BigDecimal discount = jump.getPayReduced().divide(new BigDecimal(jump.getNum()));
//                    chargeBillsService.updateDiscountMoney(discount, ids);
//                }
//            }
//            this.save(chargeBillsOrder);
//        } catch (Exception e){
//            log.error("收费异常",e);
//        }

//        return  Result.ok("收费成功");
    }

    //收费完成自动生成账单
//    @Async
    @Override
    public void autoBills(ChargeOrderReqVo reqVo){
        log.info("自动生成账单输入参数：{}", reqVo);
        try {
            //判断收费项是否为自动生成
            ChargeFeeRule feeRule = chargeFeeRuleService.getByFeeIdAndRoomId(reqVo.getFeeId(),reqVo.getRoomId());
            if (feeRule == null){
                log.warn("自动生成收费项房间：{}未查询到收费项信息id=：{}", reqVo.getRoomId(), reqVo.getFeeId());
                return;
            }
            if (!feeRule.getIsAuto()){
                log.warn("缴费收费项不需要自动生成");
                return;
            }
            ChargeBills chargeBills = new ChargeBills();
            chargeBills.setFeeitemId(reqVo.getFeeId());
            chargeBills.setRoomId(reqVo.getRoomId());
            List<ChargeBills> list = chargeBillsService.getChargeBills(chargeBills);//获取账单信息
            if (list.size() > 0){
                log.warn("缴费账单还有没有缴费数据");
                return;
            }
            ChargeGenerateBills chargeGenerateBills = new ChargeGenerateBills();
            chargeGenerateBills.setFeeRuleId(feeRule.getId());
            chargeGenerateBills.setRoomIds(Arrays.asList(reqVo.getRoomId()));
            chargeGenerateBills.setGenerateMode(2);//默认按照周期生成
            chargeGenerateBills.setMonths(12);
            chargeGenerateBills.setBillsExp("自动生成账单");
            Result<String> res = chargeBillsService.createChargeBillsNew(chargeGenerateBills);//生成账单
            log.info("自动生成账单返回：{}",res.getMessage());
        }catch (JeecgBootException e){
            log.error("自动生成账单异常",e);
        }
    }

    @Override
    public Result chargeBlueInvoice(ChargeBillsOrder chargeBillsOrder) {
        if (null == chargeBillsOrder){
            log.warn("日常收费开票订单信息为空！");
            return Result.error("开票失败！");
        }
        if (StringUtils.isEmpty(chargeBillsOrder.getBillids())){
            log.warn("日常收费开票账单集合空！");
            return Result.error("开票失败！");
        }
        if (StringUtils.isEmpty(chargeBillsOrder.getInvoiceType()) || !InvoiceTypeEnum.INVOICE_TYPE_ELE.getCode().equals(chargeBillsOrder.getInvoiceType())){
            log.warn("日常收费开票类型为不开票！");
            return Result.error("开票失败！");
        }
        // todo 后续配置在表里
        if (ComUtil.isLastDayOfMonth(new Date())){
            log.warn("当月最后一天停止开票");
            return Result.error("当月最后一天停止开票!");
        }
        // 电子发票请求插入对象
        ChargeInvoiceRequest invoiceReqDetail = new ChargeInvoiceRequest();
        invoiceReqDetail.setId(String.valueOf(IdWorker.getId()));
        invoiceReqDetail.setProjectId(chargeBillsOrder.getProjectId());
        invoiceReqDetail.setGmfMc(chargeBillsOrder.getInvoiceName());
        invoiceReqDetail.setMoney(chargeBillsOrder.getPayFee());
        invoiceReqDetail.setCustomerId(chargeBillsOrder.getUserId());
        invoiceReqDetail.setBillIds(chargeBillsOrder.getBillids());
        invoiceReqDetail.setPayMethod(chargeBillsOrder.getPayType());
        invoiceReqDetail.setCreateBy(chargeBillsOrder.getCreateBy());
        invoiceReqDetail.setPayMode(chargeBillsOrder.getPayMode());
        invoiceReqDetail.setCreateTime(new Date());
        invoiceReqDetail.setDelFlag("0");
        invoiceReqDetail.setRemarks(ComUtil.dateTimeFmt(new Date(), "yyyy-MM-dd" ) + "\n" + chargeBillsOrder.getInvoiceAddress());
        invoiceReqDetail.setOrderNum(chargeBillsOrder.getSn());
        invoiceReqDetail.setTenantId(chargeBillsOrder.getTenantId());
        invoiceReqDetail.setRoomId(chargeBillsOrder.getRoomId());
        if (StringUtils.isNotEmpty(chargeBillsOrder.getInvoiceEmail())) {
            invoiceReqDetail.setEmail(chargeBillsOrder.getInvoiceEmail());
        }
        if (StringUtils.isNotEmpty(chargeBillsOrder.getInvoiceMobile())) {
            invoiceReqDetail.setTel(chargeBillsOrder.getInvoiceMobile());
        }
        if (StringUtils.isNotEmpty(chargeBillsOrder.getInvoiceEin())) {
            invoiceReqDetail.setEin(chargeBillsOrder.getInvoiceEin());
        }
        if (StringUtils.isNotEmpty(chargeBillsOrder.getInvoiceAccount())) {
            invoiceReqDetail.setAccount(chargeBillsOrder.getInvoiceAccount());
        }
        if (StringUtils.isNotEmpty(chargeBillsOrder.getInvoiceAddress())) {
            invoiceReqDetail.setAddress(chargeBillsOrder.getInvoiceAddress());
        }
        try {
            // 申请开票
            double maxMoney = 9999,tempAmount = 0;
            List<ChargeBills> billsList = chargeBillsService.getBillsByIds(Arrays.asList(chargeBillsOrder.getBillids().split(",")));   //findByOrderId(chargeBillsOrder.getId());
            List<String> billIds = new ArrayList<>();
            log.info("{}:开始开票,订单金额:{},预估开票:{}张",chargeBillsOrder.getSn(),chargeBillsOrder.getPayFee(),chargeBillsOrder.getPayFee()/maxMoney );
            int blueCount = 0;
            for (int i =0; i < billsList.size(); i++){
                ChargeBills temp = billsList.get(i);
                if ((tempAmount + temp.getPay().doubleValue()) < maxMoney){
                    tempAmount = tempAmount + temp.getPay().doubleValue();// 未超过开票上限金额
                    billIds.add(temp.getId());
                }else {
                    // 超过开票上限金额 请求开票 重置临时累计金额
                    invoiceReqDetail.setMoney(tempAmount);
                    invoiceReqDetail.setBillIds(String.join(",", billIds));
                    try{
                        boolean res = feignChargeService.openBlue(JSON.toJSONString(invoiceReqDetail), invoiceReqDetail.getTenantId());
                        if (res)blueCount++;
                    }catch (Exception e){
                        log.error("{}:开票失败",chargeBillsOrder.getSn(),e);
                    }
                    Thread.sleep(1000);
                    billIds.clear();
                    tempAmount = temp.getPay().doubleValue();
                    billIds.add(temp.getId());
                }
                if (billsList.size() == (i+1)){
                    // 总金额超过上限金额/尾差
                    invoiceReqDetail.setMoney(tempAmount);
                    invoiceReqDetail.setBillIds(String.join(",", billIds));
                    boolean res = feignChargeService.openBlue(JSON.toJSONString(invoiceReqDetail), invoiceReqDetail.getTenantId());
                    if (res)blueCount++;
                }
            }
            log.info("{}:结束开票,订单金额:{},实际开票:{}张",chargeBillsOrder.getSn(),chargeBillsOrder.getPayFee(),blueCount);
            if (blueCount == 0){
                return Result.error("电票开具失败!");
            }
            return Result.ok("开票成功！");
        }catch (Exception ex){
            log.error("电票开具失败:{}",ex);
            return Result.error("开票失败！");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ChargeBillsOrder chargePayNotify(ChargePayNotify stu) {
        log.info("物业费支付回调销账接受参数:{}",stu);
        ChargeBillsOrder order = chargeBillsOrderMapper.getOrderBySn(stu.getOrderId());
        if (order == null) {//通知成功
            return null;//销账失败
        }
        if (order.getPayStatus() == 1) {//已支付。直接结束
            return null;
        }
        //判断在队列中是否存在 -- 防止重复回调
        if (payQueue.contains(stu.getOrderId())) {
            log.warn("账单支付中transNo:{},sn:{}",stu.getTransNo(),stu.getOrderId());
            return null;
        }
        payQueue.add(stu.getOrderId());
        try {
            //更新订单表
            chargeBillsOrderMapper.updatePayStatus(stu.getOrderId(), "", stu.getPaymentTime(), stu.getTransNo());
            order.setPayTime(DateUtils.str2Date(stu.getPaymentTime(),DateUtils.datetimeFormat));
            if (null != order.getBillids()) {
                List<ChargeBills> billsList = chargeBillsService.getBillsByIds(Arrays.asList(order.getBillids().split(",")));
                ChargeOrderReqVo reqVo = new ChargeOrderReqVo();
                BigDecimal paySum = BigDecimal.ZERO;
                for (ChargeBills bills:billsList){
                    BigDecimal pay = bills.getDue().subtract(bills.getPayReduced());
                    paySum = paySum.add(pay);
                }
                BigDecimal discount = paySum.subtract(new BigDecimal(order.getPayFee()));
                if (discount.compareTo(BigDecimal.ZERO) > 0){
                    reqVo.setIsDiscount(true);
                    reqVo.setDiscount(discount);
                }
                reqVo.setBillsList(billsList);
                if(billsList.size() > 0){
                    billsList = this.refreshChargeBills(reqVo,order);
                    chargeBillsService.updateBillsBatch(billsList);
//                    chargeBillsOrderMapper.updateBillsByIds(arrayList, stu.getPaymentTime(), "",order.getUserId(),order.getId(),new Date());
                }
            }
            order.setPayStatus(PayStatusEnum.PAY_STATUS_YES.getCode());
            this.chargeBlueInvoice(order);
            return order;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            payQueue.remove(stu.getOrderId());
        }

        return null;
    }

    @Override
    // 回调根据订单号获取到对应的支付开票信息
    public ChargeBillsOrder getBillOrderBySn(String sn) {
        return chargeBillsOrderMapper.getOrderBySn(sn);
    }


    /**
     * 多表联查分页
     *
     * @param page
     * @param billsOrder
     * @return
     */
    @Override
    public List<ChargeBillsOrder> listByProject(Page<ChargeBillsOrder> page, ChargeBillsOrder billsOrder) {
        return chargeBillsOrderMapper.listByProject(page,billsOrder);
    }

    @Override
    public Result<ChargeInvoice> unLineQRCodeCharge(ChargeOrderReqVo reqVo) {
        try {
            log.info("请求配置参数roomId:{},收费项id:{}",reqVo.getRoomId(),reqVo.getFeeId());
            // 获取通用支付配置
            ChargePayConfig payConfig = chargePayConfigMapper.getConfigByPid(reqVo.getProjectId(),PayModeEnum.PAY_MODE_SCANNER.getCode());
            // 根据收费和房间获取支付配置
            PayAccountConfig rConfig = chargePayConfigMapper.getPayConfigByRid(reqVo.getRoomId(), reqVo.getFeeId(), PayModeEnum.PAY_MODE_SCANNER.getCode());
            // 根据收费和楼宇获取支付配置
            PayAccountConfig fConfig = chargePayConfigMapper.getPayConfigByFid(reqVo.getFloorId(), reqVo.getFeeId(), PayModeEnum.PAY_MODE_SCANNER.getCode());
            ChargeFeeitem feeItem = chargeFeeitemService.getById(reqVo.getFeeId());
            if (feeItem.getFeeName().indexOf("水") != -1 || feeItem.getFeeName().indexOf("电") != -1){
                if (null != fConfig){
                    BeanUtils.copyProperties(fConfig, payConfig);
                }
            }else {
                if (null == rConfig){
                    if (null != fConfig){
                        BeanUtils.copyProperties(fConfig, payConfig);
                    }
                }else {
                    BeanUtils.copyProperties(rConfig, payConfig);
                }
            }
            if (null == payConfig){
                return Result.error("暂无项目支付配置!");
            }
            //订单信息
            ChargeBillsOrder chargeBillsOrder = new ChargeBillsOrder();
            //临时存放项目代号，用于生成账单时的项目代号
            String projectCode = sysDepartMapper.getProjectCode(reqVo.getProjectId());
            chargeBillsOrder.setVerifyAdminId(projectCode);
            chargeBillsOrder.setSn(StringUtils.createSn(projectCode, 3));
            chargeBillsOrder.setProjectId(reqVo.getProjectId());
            chargeBillsOrder.setFloorId(reqVo.getFloorId());
            chargeBillsOrder.setRoomId(reqVo.getRoomId());
            chargeBillsOrder.setFeeitemId(reqVo.getFeeId());
            chargeBillsOrder.setTenantId(payConfig.getTenantId());
            chargeBillsOrder.setPayFee(reqVo.getPay().doubleValue()); //实收金额
            chargeBillsOrder.setPayDue(reqVo.getDue());
            chargeBillsOrder.setPayReduced(reqVo.getDue().subtract(reqVo.getPay()));
            chargeBillsOrder.setPayMode(PayModeEnum.PAY_MODE_SCANNER.getCode());//支付类型
            chargeBillsOrder.setPayChannel(payConfig.getChannel());
            chargeBillsOrder.setPayStatus(PayStatusEnum.PAY_STATUS_NO.getCode());
            chargeBillsOrder.setStatus(1); //默认账单有效
            chargeBillsOrder.setInvoiceType(reqVo.getInvoiceType());
            chargeBillsOrder.setInvoiceEmail(reqVo.getInvoiceEmail());
            chargeBillsOrder.setInvoiceMobile(reqVo.getInvoiceMobile());
            chargeBillsOrder.setInvoiceName(reqVo.getInvoiceName());
            String billIds = reqVo.getBillsList().stream().map(ChargeBills::getId).collect(Collectors.joining(","));
            chargeBillsOrder.setBillids(billIds);
//       List<ChargeBills> billsList =  this.refreshChargeBills(reqVo, chargeBillsOrder);
            String preStr = reqVo.getPayQRCode().substring(0, 2);
            String sn = StringUtils.createSn(projectCode, 3);
            if ("FFT".equals(payConfig.getChannel())){ // 付费通支付通道
                String payResCode = "-1";
                String request = "";
                JSONObject payRes = null;
                //调用银行接口
                List<Object> list = new ArrayList<Object>();
                FFTFeeItem feeMoney = new FFTFeeItem();
                feeMoney.setSubjectName("物业费");
                feeMoney.setDetailAmt(chargeBillsOrder.getPayFee().toString());
                list.add(feeMoney);
                FFTCreateOrder fftCreateOrder = new FFTCreateOrder();
                fftCreateOrder.setReqNo(chargeBillsOrder.getSn());
                fftCreateOrder.setOrgNo(payConfig.getOrgNo());
                fftCreateOrder.setVillageName(payConfig.getProjectName());

                if (preStr.equals("28")){ // 支付宝二维码
                    chargeBillsOrder.setPayType(PayTypeEnum.PAY_METHOD_ALIPAY.getCode());
                    fftCreateOrder.setPaymentType("03");
                }else {
                    chargeBillsOrder.setPayType(PayTypeEnum.PAY_METHOD_WEIXINPAY.getCode());
                    fftCreateOrder.setPaymentType("04");
                }
                fftCreateOrder.setPaymentModel("00");
                fftCreateOrder.setOrderAmt(new BigDecimal(chargeBillsOrder.getPayFee()));
                fftCreateOrder.setNotifyUrl(payConfig.getNotifyUrl());
                fftCreateOrder.setOriOrderDetails(list);
                fftCreateOrder.setAddress(payConfig.getAddress());
                fftCreateOrder.setCity(payConfig.getCity());
                fftCreateOrder.setProvince(payConfig.getProvince());
                fftCreateOrder.setCounty(payConfig.getCounty());
                log.info("物业费加密参数:{}",fftCreateOrder);
                request = JSONObject.toJSONString(fftCreateOrder);
                String cipher = Sm4Util.encryptEcb(fftEncryptKey, request);
                try {
                    payRes = ComUtil.doPost(payConfig.getPayUrl()+"/ori/createOrder",cipher,fftEncryptKey);
                    log.info("物业费返回json========="+ payRes);
                    payResCode = payRes.getString("returnCode");
                }catch (Exception e){
                    log.error("物业缴费调用下单接口异常:{}",e);
                    return org.jeecg.common.api.vo.Result.error("物业缴费调用银行支付接口繁忙！");
                }
                chargeBillsOrder.setRequest(request);
                if ("0000".equals(payResCode)){
                    String  data = payRes.getString("data");
                    JSONObject jsonObject = JSONObject.parseObject(data);
                    String transNo = jsonObject.getString("transNo");
                    chargeBillsOrder.setTransactionNumber(transNo);
                    chargeBillsOrder.setResponse(JSONObject.toJSONString(jsonObject));
                    chargeBillsOrder.setPayMode(PayModeEnum.PAY_MODE_SCANNER.getCode());
                    chargeBillsOrder.setId(String.valueOf(IdWorker.getId()));
                    chargeBillsOrderMapper.insert(chargeBillsOrder);
                    Map<String, String> param = new HashMap<>();
                    param.put("payUserCode", reqVo.getPayQRCode());
                    param.put("transNo", transNo);
                    String paramStr = JSONObject.toJSONString(param);
                    String jsonmin = Sm4Util.encryptEcb(fftEncryptKey, paramStr);
                    String url = payConfig.getPayUrl() +"/ori/payOrder";
                    try {
                        JSONObject res = ComUtil.doPost(url, jsonmin, fftEncryptKey);
                        log.info("物业费付费通ori/payOrder请求结果=========" + res);
                        String code = res.getString("returnCode");
                        String msg = res.getString("returnMsg");
                        if ("0000".equals(code)){
                            String queryData = "00";
                            final long timeInterval = 5000;
                            int i = 1;
                            Map<String, String> qParam = new HashMap<>();
                            qParam.put("transNo", transNo);
                            String qParamStr = JSONObject.toJSONString(qParam);
                            String qJsonMin = Sm4Util.encryptEcb(fftEncryptKey, qParamStr);
                            String queryUrl = payConfig.getPayUrl() +"/ori/queryPayResult";
                            while (i <= 20){
                                try {
                                    JSONObject queryRes = ComUtil.doPost(queryUrl, qJsonMin, fftEncryptKey);
                                    log.info("物业费付费通ori/queryPayResult订单查询结果=========" + queryRes);
                                    queryData = queryRes.getString("data");
                                    if ("02".equals(queryData)){
                                        ChargePayNotify stu = new ChargePayNotify();
                                        stu.setTransNo(transNo);
                                        stu.setOrderId(chargeBillsOrder.getSn());
                                        stu.setPaymentAmt(chargeBillsOrder.getPayDue().toString());
                                        stu.setPaymentTime(DateUtils.date2Str(new Date(),DateUtils.yyyymmddhhmmss));
                                        this.chargePayNotify(stu);
//                                        autoBills(chargeInvoice);
                                        break;
                                    }else if ("03".equals(queryData)){
                                        log.info("物业费支付查询状态为支付失败,订单号:{}",transNo);
                                        break;
                                    }else {
                                        Thread.sleep(timeInterval);
                                    }
                                }catch (Exception ex){
                                    log.error("物业费支付状态查询异常:{},执行次数:{},订单号:{}",ex,i,transNo);
                                    return Result.error("支付接口请求失败");
                                }finally {
                                    i++;
                                }
                            }
                            return Result.ok(queryData);
                        }else {
                            return Result.error(msg);
                        }
                    }catch (Exception ex){
                        log.info("物业费付费通ori/payOrder请求失败========", ex);
                        return Result.error("物业费支付接口请求失败");
                    }
                }else {
                    return Result.error("物业费银行下单失败!");
                }
            }else if("weixin".equals(payConfig.getChannel())&& !preStr.equals("28")){
                String nonce_str = UUID.randomUUID().toString().replace("-", "");
                SortedMap<String, String> paramsMap = new TreeMap<>();
                paramsMap.put("appid", payConfig.getAppId());
                paramsMap.put("mch_id", payConfig.getMchId());
                paramsMap.put("sub_appid", payConfig.getSubAppId());
                paramsMap.put("sub_mch_id", payConfig.getSubMchid());
                paramsMap.put("auth_code", reqVo.getPayQRCode());
                paramsMap.put("nonce_str", nonce_str);
                paramsMap.put("body", payConfig.getProjectName() + "物业费" + sn);
                paramsMap.put("out_trade_no", sn);
                paramsMap.put("total_fee",  new BigDecimal(chargeBillsOrder.getPayFee()).multiply(new BigDecimal(100)).intValue()+"");
                //paramsMap.put("trade_type", "MICROPAY");
                paramsMap.put("spbill_create_ip", "127.0.0.1");
                // paramsMap.put("notify_url", payConfig.getNotifyUrl());
                log.info("w物业费请求参数{}"+paramsMap);
                paramsMap.put("sign", WXPayUtil.createSign(paramsMap, payConfig.getEncryptKey()));
                Map<String, String> map = UnifiedOrderWxPay.toMchPay(payConfig.getPayUrl(), paramsMap);
                log.info("支付请求结果"+map);

                if (map.get("return_code").equalsIgnoreCase("SUCCESS")){
                    chargeBillsOrder.setPayType(PayTypeEnum.PAY_METHOD_WEIXINPAY.getCode());
                    chargeBillsOrder.setPayMode(PayModeEnum.PAY_MODE_SCANNER.getCode());
                    chargeBillsOrder.setResponse(map.toString());
                    chargeBillsOrder.setPayMode(PayModeEnum.PAY_MODE_SCANNER.getCode());
                    chargeBillsOrder.setId(UUID.randomUUID().toString().replace("-",""));
                    chargeBillsOrder.setCreateTime(new Date());
                    chargeBillsOrder.setTransactionNumber(map.get("out_trade_no"));
                    chargeBillsOrderMapper.insert(chargeBillsOrder);
                    String timeStamp = String.valueOf(System.currentTimeMillis() / 1000);
                    //查询支付结果
                    if (map.get("return_code").equalsIgnoreCase("SUCCESS")){
                        SortedMap<String, String> queryMap = new TreeMap<>();
                        //生成签名
                        String lastSign = "appid="+payConfig.getAppId()+"&mch_id"+payConfig.getMchId()+"&sub_mch_id"+payConfig.getSubMchid()+
                                "&out_trade_no"+sn+"&nonce_str"+nonce_str;
                        //支付密钥
                        String key = "&key=" + payConfig.getEncryptKey();
                        String endSign = WXPayUtil.sign(lastSign, key, "UTF-8").toUpperCase();
                        queryMap.put("appid",payConfig.getAppId());
                        queryMap.put("mch_id",payConfig.getMchId());
                        queryMap.put("sub_mch_id",payConfig.getSubMchid());
                        queryMap.put("out_trade_no",sn);
                        queryMap.put("nonce_str",nonce_str);
                        queryMap.put("sign",endSign);
                        final long timeInterval = 5000;
                        int i = 1;
                        while (i<=20){
                            try {
                                Map<String, String> endMap = UnifiedOrderWxPay.toMchPay("https://api.mch.weixin.qq.com/pay/orderquery", paramsMap);
                                log.info("endMap"+endMap);
                                if (endMap.get("trade_state").equalsIgnoreCase("SUCCESS")){
                                    ChargePayNotify stu = new ChargePayNotify();
                                    stu.setOrderId(chargeBillsOrder.getSn());
                                    stu.setPaymentAmt(chargeBillsOrder.getPayDue().toString());
                                    stu.setPaymentTime(endMap.get("time_end"));
                                    stu.setTransNo(endMap.get("transaction_id"));
                                    this.chargePayNotify(stu);
                                    break;
                                }else {
                                    Thread.sleep(timeInterval);
                                }
                            }catch (Exception e){
                                e.printStackTrace();
                            }
                            finally {
                                i++;
                            }
                        }
                    }
                    // chargeInvoiceResult.setMessage(payConfig.getCompanyName());
                    return Result.ok("支付成功");
                }else {
                    return Result.error("支付失败");
                }
            }else if ("weixin".equals(payConfig.getChannel())&&preStr.equals("28")){
                String APP_ID = "2021002149652318";
                String PRIVATE_KEY = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCfvfmSTCHeNc8ZtE9CuY571QpZfAjk7chOvQQ0uQhg3MxXFiFqdlZ4Nlzq11jZkgAtBMwjaw6jmwJeEiLp/r7tCpTaMcDTjkbPgijGwXFnnUXipDKQ2/6SgKk9FBfxZZdA5kjLN6eMT8pXsd/oiIf3DyQKUXz38Qd8y5HA0bMsRnPnyPrA1M9Sc0iqOeynAvJR3KpPpkEGzI3xsvOMxBMJFKUYQyqeH7tFYKWhaBuRQ2Btcc1eX4csJIOlH7OfLEh7l4Atq0e38b7JCDnwzMol7PbqPMLXHSpmrsnf9lJxcWtxOPit3JmEk21jB6+Yhc4DJ4TufUkqzyHGg43XWXrVAgMBAAECggEAJvR/Hiwuvi/FF3GfOphhpNUpNvVGff12sazqj6jn4Cc4NayR7ZJ6N8qaEjL92eD+5fubhK+g3Ej65NHrbcDP8qJ39lXXvj+eCRCmvQGDlE8IMeL06dqcVEHIA7sYs6egoRUHf3dNBqyWnZglEGHrNlac5V9F6HkA6HAEVU9OMGeDCodQEQK+nrMJ0gKDd0O97KHQ/F3OaV+j0aDWtTh77p/8sbt1Mqrlf1gnXfrASp2tyV3Jr5bDPEX1g1PbgBk3W4pba6RwAgCQ7CUWkawD0sCuOE+N8fbLIpS2QlhgLE1UhNLC8BNQVWzY4Ih6+6jwUVULH3g2rQxWIxKQnih66QKBgQDZrbX7C5abDCM4GPOe9YAwfKhKph6+i3sjiZ3GXDNF+0fdaPqD5uY42s2NlKWYHladK++8DwD8Pk2nHKSPA7amNC1ASUEn1hQ9KmMhlGXL3tZJ9BR9vuB/p9XhhpF1urwljaMvZgkwXlgspyqkpXYzGZNzKiSo81Uup8a+/iZTHwKBgQC73TIxQza2s8kOd+WQI8OUPVNsN6kaYLH8Nt1leeCFLea9eD5SG0WNZpuSdRlsQ9UU5iXqRKFK54qF4xbK+JvckotLnhDQTDc5dpFRRt1f4RPnqvC3HmBGAI5ADARMF5fRmIEQERqvM0iCzVVYidsZMbOmT1REQMha3LtnQ6uHiwKBgAYzf6quMtUp7Frtwwr1PXikJHsz7k5JVPG3Oupqt/83YF27Xt+hFU/rU83DvU/vFVKW7NZzqviEoduv4jQ8y9hCRkO9koCbBaqUaYyMWLYNHBexP2Axrt2UH3C0T7KF5lQ/i7WO95YMKgDjpkBYglyETwIJ4k951yRkHTJVtSvLAoGBALpuR5ollo13GyZ1i2YgZ72bokb5caJQpTCjDdDfQxVHOP1773SxxbMOSYLtHD6ZjkMAJk42r03TO1+kvYDNeHdLIlr3UL41dHRdGtbqmVPF3GgB9oHy7h1p/cDHbBhLLYl9a08TekS1gtbziCemHr0A2sRHY1ucYnfxJzTSLc4DAoGANVQz9SB9bx1BUELdXPWnMP8aArTXkHkyLrVnZhDQproaUlSya6R5IoMZnuW6Mx9jcLDjY1hSfsj7BzqFnLCQEy+AJoTADJsRR/rY4v990XXWyrN5G1K4DrV+c0/DkgF6fZcAhRuc0PCm041USiBD38x9Gup+VzYtOSZDQAmMDx0=";
                String PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3A/aMMbABLSX0M2bAG+OkA1EoD2d5KFikRseCCYF1+i8h9ddDnupZoZLkNx+qSbe47VNwNSp3LM7lbRLZKq7RfnGZaJdatLC/K2QHf7HXqoDuPtBIqas0ZViELnCIbaU9Qd2VBwALQg0YuxqcQVj+rG/nLVs9d7cuw2JlYlasReM1YnqoJER191wA+T0jjNuUyCu+3wffabIxNXDJ56KI/AdU6G5NIJjGLuttKR4zJZwWbl8Rb/y62UWkKCvdhla5SEhG6+pHUHTwhNtsHT+JkFaQ//b4nq+QbxvArosc6ruQ7zgCucmv16rw5lc6UVyT0Ld0LiYyPmJdPcZQ+Ht7QIDAQAB+7QqU2jHA045Gz4IoxsFxZ51F4qQykNv+koCpPRQX8WWXQOZIyzenjE/KV7Hf6IiH9w8kClF89/EHfMuRwNGzLEZz58j6wNTPUnNIqjnspwLyUdyqT6ZBBsyN8bLzjMQTCRSlGEMqnh+7RWCloWgbkUNgbXHNXl+HLCSDpR+znyxIe5eALatHt/G+yQg58MzKJez26jzC1x0qZq7J3/ZScXFrcTj4rdyZhJNtYwevmIXOAyeE7n1JKs8hxoON11l61QIDAQAB";
                AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do",APP_ID,PRIVATE_KEY,"json","GBK",PUBLIC_KEY,"RSA2");
                AlipayTradePayRequest request = new AlipayTradePayRequest();
                HashMap<String, Object> bizCotent = new HashMap<>();
                bizCotent.put("out_trade_no",sn);
                bizCotent.put("scene","bar_code");
                bizCotent.put("auth_code",reqVo.getPayQRCode());
                bizCotent.put("total_amount",chargeBillsOrder.getPayFee());
                bizCotent.put("subject","物业费");
                bizCotent.put("body","物业费");
                bizCotent.put("timeout_express","90m");
                bizCotent.put("product_code","FACE_TO_FACE_PAYMENT");
                String s = JSONObject.toJSONString(bizCotent);
                request.setBizContent(s);
                String app_auth_token = payConfig.getZfbFz();
                request.putOtherTextParam("app_auth_token", app_auth_token);
                request.setNotifyUrl(payConfig.getNotifyUrl());
                int i = 0;
                final long timeInterval = 5000;
                boolean flag = false;
                try {
                    chargeBillsOrder.setPayType(9);
                    chargeBillsOrder.setPayChannel("ALNP");
                    // utilityBillsOrder.setTransactionNumber(response.getTradeNo());
                    chargeBillsOrder.setPayMode(PayModeEnum.PAY_MODE_SCANNER.getCode());
                    // utilityBillsOrder.setResponse(response.getBody());
                    chargeBillsOrder.setId(UUID.randomUUID().toString().replace("-",""));
                    chargeBillsOrder.setCreateTime(new Date());
                    chargeBillsOrderMapper.insert(chargeBillsOrder);
                    AlipayTradePayResponse response = alipayClient.execute(request);
                    /*if (response.getCode().equals("10000")){*/

                    /* }*/
                    AlipayClient alipayClientQurey = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do",APP_ID,PRIVATE_KEY,"json","GBK",PUBLIC_KEY,"RSA2");
                    AlipayTradeQueryRequest requestQurey = new AlipayTradeQueryRequest();
                    HashMap<String, Object> bizCotentQurey = new HashMap<>();
                    bizCotentQurey.put("out_trade_no",sn);
                    requestQurey.putOtherTextParam("app_auth_token", app_auth_token);
                    String query = JSONObject.toJSONString(bizCotentQurey);
                    requestQurey.setBizContent(query);
                    while (i<=5){
                        AlipayTradeQueryResponse responsequery = alipayClientQurey.execute(requestQurey);
                        if (responsequery.getTradeStatus().equalsIgnoreCase("TRADE_SUCCESS")){

                            flag = true;
                            break;
                        }  else {
                            Thread.sleep(timeInterval);
                        }
                        i++;
                    }
                    if (!flag){
                        return Result.error("支付失败");
                    }
                    // chargeInvoiceResult.setMessage(payConfig.getCompanyName());
                    return Result.ok("支付成功");
                }catch (Exception e){
                    e.printStackTrace();
                    return Result.error("支付失败");
                }
            } else {
                return Result.error("物业费未知的支付渠道");
            }
        } catch (Exception ex) {
            log.error("扫码枪物业费异常",ex);
            return Result.error("物业费系统繁忙，充值失败！");
        }

    }

    @Override
    @Transactional(rollbackFor=Exception.class)
    public Result<ChargeBillsOrder> refundCharge(String orderId) {
//        Result<MeterOrder> result = new Result<MeterOrder>();
        if (StringUtils.isBlank(orderId)) throw new RuntimeException("退款参数有误");
        ChargeBillsOrder chargeBillsOrder = chargeBillsOrderMapper.selectById(orderId);
        if (chargeBillsOrder == null){
            return Result.error("系统中未查到需要退款的订单！");
        }
        if (RefundStatusEnum.REFUND_STATUS_YES.getCode() == chargeBillsOrder.getRefundStatus()){
            return Result.error("当前订单已退款，请勿重复操作");
        }
        if (!PayModeEnum.PAY_MODE_OFFLINE.getCode().equals(chargeBillsOrder.getPayMode())){
            return Result.error("线上支付暂不支持退款！");
        }
        try {
//            if (InvoiceMethodEnum.INVOICE_METHOD_NO.getCode().equals(chargeBillsOrder.getInvoiceType())){
//                return Result.error("开纸质/电子发票暂不支持退款！");
//            }
            LoginUser user = SsoUtil.getLoginUser();
            //修改订单表状态
            chargeBillsOrder.setRefundStatus(RefundStatusEnum.REFUND_STATUS_YES.getCode());
            chargeBillsOrder.setRefundTime(new Date());
            chargeBillsOrder.setRefundBy(user.getId());
            chargeBillsOrder.setStatus(3);  //旧字段可能跟报表统计有关、姑且设置进去后续优化
            //修改账单状态
            List<ChargeBills>  chargeBillsList =  chargeBillsService.findByOrderId(orderId);
            //删除原账单 放在复制账单前面删除，否则roomid索引会报错
            chargeBillsService.deleteByOrderId(orderId);
            for (ChargeBills oldBills:chargeBillsList){
                //重新生成应收账单 - 复制已有的账单
                ChargeBills newBills = new ChargeBills();
                BeanUtils.copyProperties(oldBills,newBills);
                newBills.setId(String.valueOf(IdWorker.getId()));
                newBills.setZjSkrq(null);
                newBills.setPayuserName(null);
                newBills.setZjTkrq(null);
                newBills.setZjTzrq(null);
                newBills.setPayType(null);
                newBills.setInvoiceNo(null);
                newBills.setInvoiceGrnno(null);
                newBills.setMakeinvoiceDate(null);
                newBills.setBillsExp("退款生成应收账单");
                newBills.setIncome(null);
                newBills.setTaxPaid(0.0);
                newBills.setTaxRate(0.0);
                newBills.setCreateTime(new Date());
                newBills.setCreateBy(user.getId());
                newBills.setUpdateTime(new Date());
                newBills.setUpdateBy(user.getId());
                chargeBillsService.insertBills(newBills);
                //将需要退款的账单 - 移动到history记录表中
                oldBills.setParentBillsIds(newBills.getId());
            }
            if (chargeBillsList.size() > 0 ){
                chargeBillsService.insertListHistory(chargeBillsList);
            }
            this.updateById(chargeBillsOrder);

            if (chargeBillsOrder.getInvoiceType().equals(InvoiceTypeEnum.INVOICE_TYPE_ELE.getCode())){
                List<ChargeInvoiceRequest> list = chargeInvoiceRequestService.listBySn(chargeBillsOrder.getSn());
                for (ChargeInvoiceRequest temp : list){
                    feignChargeService.openRed(JSON.toJSONString(temp), temp.getTenantId());
                }
            }
        }catch (RuntimeException re){
            log.error("ChargeBillsOrderServiceImpl refundCharge 异常",re);
            throw new RuntimeException("退款处理异常",re);
//            return Result.error("退款处理异常");
        } catch (Exception e){
            log.error("ChargeBillsOrderServiceImpl refundCharge 异常",e);
            throw new RuntimeException("退款处理异常,充值失败",e);
        }
        return Result.ok(chargeBillsOrder);
    }

    @Override
    public List<ChargeInvoiceRequest> invoiceRequestListBySn(String orderNum) {
        return chargeBillsOrderMapper.invoiceRequestListBySn(orderNum);
    }

    @Override
    public ChargeInvoiceRequest invoiceRequestByFpqqlsh(String lsh) {
        return chargeBillsOrderMapper.invoiceRequestByFpqqlsh(lsh);
    }

    /**
     *
     *  招行小程序支付回调
     * */
    @Transactional(readOnly = false)
    public Integer refundNotify(String req,HttpServletRequest request) {
        JSONObject jsonObject1 = JSONObject.parseObject(req);
        String orderId = jsonObject1.getString("orderId");
        // 商户订单号
        Integer result = 0;
        // 银行交易号
        String cmbOrderId = jsonObject1.getString("cmbOrderId");
        String tradeType = jsonObject1.getString("payType");
        if ("WX".equals(tradeType)) {
            tradeType = "minipay";
        }
        //支付时间
        String paymentTime = jsonObject1.getString("txnTime");
        ChargeBillsOrder order = chargeBillsOrderMapper.getOrderBySn(orderId);
        request.setAttribute("tenantId",order.getTenantId());
        if (order == null) {
            //销账失败
            return result;
        }
        //已支付。直接结束
        if (order.getPayStatus() == 1) {
            return result;
        }
        //判断在队列中是否存在 -- 防止重复回调
        if (payQueue.contains(orderId)) {
            System.out.println("账单支付中!");
            return result;
        }
        payQueue.add(orderId);
        try {
            //更新订单表
            result = chargeBillsOrderMapper.updatePayStatus(orderId, req, paymentTime, cmbOrderId);
            if (null != order.getBillids()) {
                // 把字符串id转list Id放进billids中
                String[] billsids = order.getBillids().toString().split(",");
                List<String> arrayList = Arrays.asList(billsids);
                if(arrayList.size() > 0){
                    result = chargeBillsOrderMapper.updateBillsByIds(arrayList, paymentTime, tradeType,"",order.getId(),new Date());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            payQueue.remove(orderId);
        }
        return result;
    }

    /**
     * 计算优惠
     * @param reqVo
     * @param billsOrder
     */
    private List<ChargeBills> refreshChargeBills(ChargeOrderReqVo reqVo, ChargeBillsOrder billsOrder) {
//        LoginUser user = SsoUtil.getLoginUser();
        BigDecimal averageDiscount = BigDecimal.ZERO; //每月的平均优惠金额
        BigDecimal billsCount = new BigDecimal(reqVo.getBillsList().size()); //缴费的总账单数
        BigDecimal discount = BigDecimal.ZERO;
        if (reqVo.getIsDiscount() != null && reqVo.getIsDiscount()){
            discount = reqVo.getDiscount();
        }
        if (discount != null && BigDecimal.ZERO.compareTo(discount) < 0){ //有优惠金额
            averageDiscount = discount.divide(billsCount,2,BigDecimal.ROUND_HALF_UP);
        }
        List<ChargeBills> billsList = new ArrayList<>();
        for (int i=0;i < reqVo.getBillsList().size();i++){
            ChargeBills bills = reqVo.getBillsList().get(i);
            if (StringUtils.isBlank(billsOrder.getBillids())){
                billsOrder.setBillids(bills.getId());
            } else {
                billsOrder.setBillids(billsOrder.getBillids() + "," + bills.getId());
            }
            bills.setPayType(billsOrder.getPayType());
            bills.setZjSkrq(billsOrder.getPayTime());
            bills.setMakeinvoiceDate(reqVo.getMakeInvoiceDate());
//            bills.setUpdateBy(user.getId());
//            bills.setUpdateTime(new Date());
            bills.setInvoiceGrnno(reqVo.getInvoiceDm());
            bills.setInvoiceNo(reqVo.getInvoiceHm());
            bills.setOrderId(billsOrder.getId());
            bills.setBatchDiscountMoney(averageDiscount);
            if (i == reqVo.getBillsList().size() -1 ){ //最后一条
                bills.setBatchDiscountMoney(discount);  //用剩下的
            }
            discount = discount.subtract(averageDiscount); //总优惠 循环一次减一次
            BigDecimal payReduced = bills.getPayReduced() == null ? BigDecimal.ZERO: bills.getPayReduced();
            bills.setPay(bills.getDue().subtract(payReduced).subtract(bills.getBatchDiscountMoney())); //实收金额
            billsList.add(bills);
        }
        return billsList;
    }

    @Override
    public List<DayReportRespVo> findGroupList(DayReportReqVo dayReportReqVo){
        return chargeBillsOrderMapper.findGroupList(dayReportReqVo);
    };

    @Override
    public String getFeeNameByOrderId(String orderId,Integer refundStatus,int type){
        return chargeBillsOrderMapper.getFeeNameByOrderId(orderId,refundStatus,type);
    };

}

